import store from "./store";
import request from "../request";

import filterAsyncRoutes from "../utils/filterAsyncRoutes";

import {
  getToken,
  setToken,
  setRefreshToken,
  setUserInfo,
  clearStorage,
  getUserInfo
} from "../utils/auth";

const getDefaultState = () => {
  return {
    token: getToken(),
    routes: {},
    addRoutes: [],
    isLogin: !!getToken(),
    version: "v1.0.0",
    userInfo: getUserInfo(getToken())
  };
};

const state = getDefaultState();

const mutations = {
  SET_TOKEN: (state, { token, refreshToken }) => {
    setToken(token);
    setRefreshToken(refreshToken);
    state.token = token;
  },
  SET_USERINFO: (state, data) => {
    let { token } = data;
    setUserInfo(token, data);
    state.userInfo = data;
  },
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes;
    state.routes = { ...routes };
  }
};

const actions = {
  generateRoutes({ commit }, { roles, asyncRoutes, isAdmin }) {
    console.log("我是路由生成器", { roles, asyncRoutes, isAdmin });
    return new Promise((resolve, reject) => {
      //如果是超级管理员
      if (isAdmin === 1) {
        commit("SET_ROUTES", asyncRoutes);
        resolve(asyncRoutes);
      } else {
        let accessedRoutes = [];
        request({
          url: "/api/account/roles",
          method: "POST",
          headers: {
            "x-api-type": "app"
          }
        })
          .then(roleRouteMap => {
            for (const key in asyncRoutes) {
              let A = asyncRoutes[key];
              let B = roleRouteMap[key];
              accessedRoutes[key] = filterAsyncRoutes(A, B);
            }
            commit("SET_ROUTES", accessedRoutes);
            resolve(accessedRoutes);
          })
          .catch(error => {
            reject(error);
          });
      }
    });
  },
  /**
   * 用户信息更新
   * @param commit
   * @param fun
   * @param userInfo
   * @returns {Promise<unknown>}
   */
  userinfo({ commit }, fun) {
    return new Promise((resolve, reject) => {
      fun()
        .then(data => {
          let { token, refreshToken } = data;
          commit("SET_TOKEN", { token, refreshToken });
          commit("SET_USERINFO", data);
          resolve(data);
        })
        .catch(error => {
          reject(error);
        });
    });
  },
  /**
   * 执行用户登录
   * @param commit
   * @param fun
   * @param userInfo
   * @returns {Promise<unknown>}
   */
  login({ commit }, fun) {
    return new Promise((resolve, reject) => {
      fun()
        .then(data => {
          let { token, refreshToken } = data;
          commit("SET_TOKEN", { token, refreshToken });
          commit("SET_USERINFO", data);
          resolve(data);
        })
        .catch(error => {
          reject(error);
        });
    });
  },
  logout() {
    return new Promise((resolve, reject) => {
      try {
        clearStorage();
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
};

const storeName = "cloud_application";

export function install() {
  // 判断是否注册了模型
  if (!store.hasModule(storeName)) {
    store.registerModule([storeName], {
      namespaced: true,
      state,
      mutations,
      actions,
      getters: {
        getState: state => value => {
          return state[value];
        },
        isLogin: () => () => {
          return !!getToken();
        },
        userInfo: state => () => {
          return state["userInfo"];
        },
        routes: state => (value = "") => {
          return value ? state["routes"][value] : state["routes"];
        }
      }
    });
  }
}

export function uninstall() {
  if (store.hasModule(storeName)) {
    store.unregisterModule(storeName);
  }
}

export function getStore() {
  //执行注册
  install();
  return {
    state: store.state[storeName],
    commit(type, payload, options) {
      type = storeName + "/" + type;
      return store.commit(type, payload, options);
    },
    dispatch(type, payload) {
      type = storeName + "/" + type;
      return store.dispatch(type, payload);
    },
    getter(value) {
      let type = storeName + "/getState";
      return store.getters[type](value);
    },
    isLogin() {
      let type = storeName + "/isLogin";
      return store.getters[type]();
    },
    userInfo() {
      let type = storeName + "/userInfo";
      return store.getters[type]();
    },
    getRoutes(roles, asyncRoutes, isAdmin) {
      let type = storeName + "/generateRoutes";
      return store.dispatch(type, { roles, asyncRoutes, isAdmin });
    },
    routes(value) {
      let type = storeName + "/routes";
      return store.getters[type](value);
    }
  };
}
